<#list po.fieldNames as fieldName>
<#if fieldName == 'code'>
<#assign fieldsContainsCode=true>
</#if>
<#if fieldName == 'name'>
<#assign fieldsContainsName=true>
</#if>
</#list>
package ${abstractActionPackage};

import java.io.InputStream;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.odianyun.db.query.PageVO;
import com.odianyun.project.model.vo.ObjectResult;
import com.odianyun.project.model.vo.PageResult;
import com.odianyun.project.model.vo.ListResult;
import com.odianyun.project.model.vo.Result;
import com.odianyun.project.query.PageQueryArgs;
import com.odianyun.project.query.QueryArgs;
<#if fieldsContainsCode?? && fieldsContainsName??>
import com.odianyun.project.util.WebUtils;
import com.odianyun.util.BeanUtils;
</#if>
import com.odianyun.util.excel.exporter.ExcelExportConfig;
import com.odianyun.util.excel.parser.ExcelParseConfig;
import com.odianyun.util.io.Closer;
import com.odianyun.oms.backend.core.base.BaseController;

import ${dtoPackage}.${po.name}DTO;
import ${voPackage}.${po.name}VO;
import ${servicePackage}.${po.name}Service;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * ${po.title}
 * @date ${date}
 */
@Api(description="${po.title}")
@RequestMapping("${po.uncapitalizedName}")
@RestController
public abstract class Abstract${po.name}Controller extends BaseController {
	@Resource
	private ${po.name}Service service;

    /**
     * 分页查询
     * @date ${date}
     * @param args
     * @return PageResult<${po.name}VO>
     */
	@ApiOperation(value="分页查询", notes="{\"filters\":{\"key1\":value1, \"key2\":value2}}")
	@PostMapping("/listPage")
	public PageResult<${po.name}VO> listPage(@RequestBody PageQueryArgs args) {
		PageVO<${po.name}VO> vo = service.listPage(args);
		
		return PageResult.ok(vo);
	}

    /**
     * 列表查询
     * @date ${date}
     * @param args
     * @return ListResult<${po.name}VO>
     */
	@ApiOperation(value="列表查询", notes="{\"filters\":{\"key1\":value1, \"key2\":value2}}")
	@PostMapping("/list")
	public ListResult<${po.name}VO> list(@RequestBody QueryArgs args) {
		List<${po.name}VO> vo = service.list(args);
		
		return ListResult.ok(vo);
	}

    /**
     * 查询
     * @date ${date}
     * @param id
     * @return ObjectResult<${po.name}VO>
     */
	@ApiOperation("查询")
	@GetMapping("/getById")
	public ObjectResult<${po.name}VO> getById(@RequestParam("id") Long id) {
		return ObjectResult.ok(service.getById(id));
	}
	
	<#if fieldsContainsCode?? && fieldsContainsName??>
    /**
     * 下拉查询
     * @date ${date}
     * @param request
     * @return ListResult<Map<String, Object>>
     */
	@ApiOperation(value="下拉查询", notes="?k1=v1&k2=v2")
	@GetMapping("/select")
	public ListResult<Map<String, Object>> select(HttpServletRequest request) {
		Map<String, Object> filters = WebUtils.getParameterMap(request, "ut");
		QueryArgs args = new QueryArgs();
		if (filters != null && filters.size() > 0) {
			args.setFilters(filters);
		}
		
		args.withSelectFields("code", "name");

		List<${po.name}VO> vo = service.list(args);
		
		return ListResult.ok(BeanUtils.beans2MapsByIncludeGetters(vo, args.getSelectFields()));
	}
	</#if>

    /**
     * 添加
     * @date ${date}
     * @param u
     * @return ObjectResult<Long>
     * @throws Exception
     */
	@ApiOperation("添加")
	@PostMapping("/add")
	public ObjectResult<Long> add(@RequestBody @Valid ${po.name}DTO u) throws Exception {
		notNull(u);
		
		return ObjectResult.ok(service.addWithTx(u));
	}

    /**
     * 修改
     * @date ${date}
     * @param u
     * @return Result
     * @throws Exception
     */
	@ApiOperation("修改")
	@PostMapping("/update")
	public Result update(@RequestBody @Valid ${po.name}DTO u) throws Exception {
		notNull(u);
		fieldNotNull(u, "id");
		
		service.updateWithTx(u);
		return Result.OK;
	}

    /**
     * 删除
     * @date ${date}
     * @param ids
     * @return Result
     * @throws Exception
     */
	@ApiOperation("删除")
	@PostMapping("/delete")
	public Result delete(@RequestBody Long[] ids) throws Exception {
		notNull(ids);

		service.deletesWithTx(ids);
		return Result.OK;
	}

    /**
     * 导出
     * @date ${date}
     * @param data
     * @param req
     * @param res
     * @throws Exception
     */
	@ApiOperation("导出")
	@PostMapping("/export")
	public void export(@RequestBody Map<String, Object> data, HttpServletRequest req, HttpServletResponse res) throws Exception {
		notNull(data);
		
		QueryArgs args = new QueryArgs();
		args.setFilters(data);
		
		List<${po.name}VO> list = service.list(args);
		
		ExcelExportConfig cfg = new ExcelExportConfig();
		cfg.setAutoSizeColumn(false);
		
		mappingExportFields(cfg);
		
		super.doExport(getName(), list, cfg, req, res);
	}

    /**
     * 导入
     * @date ${date}
     * @param request
     * @return Result
     * @throws Exception
     */
	@ApiOperation("导入")
	@PostMapping("/import")
	public Result importData(MultipartHttpServletRequest request) throws Exception {
		MultipartFile multipartFile = request.getFile("fileData");
		InputStream stream = multipartFile.getInputStream();
		String filename = multipartFile.getOriginalFilename();
		
		try {
			ExcelParseConfig cfg = new ExcelParseConfig();
			cfg.setAutoMapColName(false);
			cfg.withSheetIndexes(0);
			
			mappingImportFields(cfg);
			
			List<${po.name}DTO> list = super.doImport(filename, ${po.name}DTO.class, cfg, stream);
			
			service.batchAddWithTx(list);
			
			return Result.OK;
		} finally {
			Closer.close(stream);
		}
	}
	
	private void mappingImportFields(ExcelParseConfig cfg) {
		<#list po.nonCommonFields as field>
		cfg.mapColName("${field.title}", "${field.name}");
		</#list>
	}

	private void mappingExportFields(ExcelExportConfig cfg) {
		<#list po.nonCommonFields as field>
		cfg.mapColName("${field.name}", "${field.title}");
		</#list>
	}

	private String getName() {
		return "${po.title}";
	}
	
}
